/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bombercloud.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author leoomoreira
 */
public class BomberCloudServer extends Thread {

    class Node {

        private String address;
        private int port;

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }
    }

    private int port;
    private ServerSocket serverSocket;
    private List<Node> nodes;

    public BomberCloudServer(int port) throws IOException {
        this.port = port;
        String strNodeList = bombercloud.BomberCloudServerConfig.getConfigurationValue("bombercloudnode.list");
        if (strNodeList == null || strNodeList.trim().length() == 0 || !strNodeList.contains(":")) {
            BomberCloudServerOutputMessage.printErrorMessage("There are no nodes in the configuration file");
            BomberCloudServerOutputMessage.printMessage("Please enter at least one node");
            BomberCloudServerOutputMessage.printMessage("Example: bombercloudnode.list=192.168.0.1:5623;192.168.0.2:5623");
            System.exit(-1);
        } else {
            String[] nodeList = strNodeList.split(";");
            if (nodeList == null) {
                nodeList = new String[]{strNodeList};
            }
            nodes = new ArrayList<Node>();
            for (int i = 0; i < nodeList.length; i++) {
                if (!nodeList[i].contains(":")) {
                    BomberCloudServerOutputMessage.printErrorMessage("There are no nodes in the configuration file");
                    BomberCloudServerOutputMessage.printMessage("Please enter at least one node");
                    BomberCloudServerOutputMessage.printMessage("Example: bombercloudnode.list=192.168.0.1:5623;192.168.0.2:5623");
                    System.exit(-1);
                } else {
                    Node node = new Node();
                    try {
                        node.setAddress(nodeList[i].split(":")[0]);
                        node.setPort(Integer.parseInt(nodeList[i].split(":")[1]));
                    } catch (Exception ex) {
                        BomberCloudServerOutputMessage.printErrorMessage("There are no nodes in the configuration file");
                        BomberCloudServerOutputMessage.printMessage("Please enter at least one node");
                        BomberCloudServerOutputMessage.printMessage("Example: bombercloudnode.list=192.168.0.1:5623;192.168.0.2:5623");
                        System.exit(-1);
                    }
                    nodes.add(node);
                }
            }
        }
        for (Node node : nodes) {
            BomberCloudServerOutputMessage.printMessage(node.getAddress() + ":" + node.getPort() + " node loaded");
        }
        serverSocket = new ServerSocket(port);
    }

    @Override
    public void run() {
        if (serverSocket != null && !serverSocket.isClosed()) {
            BomberCloudServerOutputMessage.printMessage("BomberCloudServer is running on port " + port);
        }
        while (serverSocket != null && !serverSocket.isClosed()) {
            try {
                Socket socket = serverSocket.accept();
                String nodeAddress;
                int nodePort;
                synchronized (this) {
                    Node node = nodes.remove(0);
                    nodes.add(node);
                    nodeAddress = node.getAddress();
                    nodePort = node.getPort();
                }
                BomberCloudServerOutputMessage.printMessage("Accepted a new connection to " + nodeAddress + ":" + nodePort);
                BomberCloudServerThread thread = new BomberCloudServerThread(socket, nodeAddress, nodePort);
                thread.start();
            } catch (IOException ex) {
                BomberCloudServerOutputMessage.printErrorMessage(ex.getMessage());
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args == null || args.length != 1) {
            BomberCloudServerOutputMessage.printErrorMessage("Invalid number of parameters");
            BomberCloudServerOutputMessage.printMessage("Enter only the connection port");
            BomberCloudServerOutputMessage.printMessage("Example: java -jar bombercloud-node.jar 6789");
            System.exit(-1);
        }
        int port = -1;
        try {
            port = Integer.parseInt(args[0]);
        } catch (Exception ex) {
            BomberCloudServerOutputMessage.printErrorMessage(ex.getMessage());
            System.exit(-1);
        }
        try {
            BomberCloudServer bomberCloudServer = new BomberCloudServer(port);
            bomberCloudServer.start();
        } catch (IOException ex) {
            BomberCloudServerOutputMessage.printErrorMessage(ex.getMessage());
            System.exit(-1);
        }
    }

}
